package com.smile.service.user;


import com.smile.auth.JwtUserEntity;
import com.smile.entity.BaseEntity;
import com.smile.entity.sys.MenuEntity;
import com.smile.entity.sys.RoleEntity;
import com.smile.entity.sys.UserEntity;
import com.smile.mapper.sys.MenuMapper;
import com.smile.mapper.sys.RoleMapper;
import com.smile.mapper.sys.UserMapper;
import com.smile.service.sys.UserService;
import com.smile.util.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private PasswordUtil passwordUtil;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuMapper menuMapper;

    /**
     * 根据用户名查询用户信息
     *
     * loadUserByUsername 只是认证流程中的数据加载阶段
     * 真正的密码验证由 Spring Security 框架自动完成
     * 框架会自动比对 authenticationToken 中的密码和 UserDetails 中的密码
     * 只有验证通过后，才会将认证信息放入 SecurityContext
     *
     *
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        UserEntity userEntity = userMapper.findByUserName(username);
        if (Objects.isNull(userEntity)) {
            throw new UsernameNotFoundException("用户不存在");
        }


        //通过用户名查询用户信息 封装到JwtUserEntity
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //填充用户权限
        fillUserAuthority(userEntity, authorities);
        JwtUserEntity jwtUserEntity = new JwtUserEntity(userEntity.getId(), username, userEntity.getPassword(), authorities, null);
        return jwtUserEntity;

    }

    //填充用户权限
    private void fillUserAuthority(UserEntity userEntity, List<SimpleGrantedAuthority> authorities) {
        List<RoleEntity> roleEntities = roleMapper.findRoleByUserId(userEntity.getId());
        if (CollectionUtils.isEmpty(roleEntities)) {
            return;
        }

        Set<String> permissionSet = roleEntities.stream()
                .filter(x -> StringUtils.hasLength(x.getPermission())).map(RoleEntity::getPermission)
                .collect(Collectors.toSet());

        fillRoleMenu(roleEntities, permissionSet);
        if (!CollectionUtils.isEmpty(permissionSet)) {
            authorities.addAll(permissionSet.stream().map(x -> new SimpleGrantedAuthority(x)).collect(Collectors.toList()));
        }

    }


    // 填充角色权限
    private void fillRoleMenu(List<RoleEntity> roleEntities, Set<String> permissionSet) {
        //获取角色权限ID
        List<Long> roleIdList = roleEntities.stream().map(RoleEntity::getId).collect(Collectors.toList());

        List<MenuEntity> menuList = menuMapper.findMenuByRoleIdList(roleIdList);
        if (CollectionUtils.isEmpty(menuList)) {
            return;
        }

        for (MenuEntity menuEntity : menuList) {
            if (StringUtils.hasLength(menuEntity.getPermission())) {
                Set<String> menuPermissionSet = Arrays.stream(menuEntity.getPermission().split(",")).collect(Collectors.toSet());
                permissionSet.addAll(menuPermissionSet);
            }
        }

    }
}